package com.ruoyi.framework.config;

import com.ruoyi.common.core.domain.model.LoginUser;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.impl.serialization.PlainJavaSerializer;
import org.ehcache.jsr107.Eh107Configuration;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.spi.CachingProvider;
import java.io.File;
import java.time.Duration;

@Configuration
public class Ehcache3Config {
    private final static String TEMP_CACHE = "temp_cache";
    private final static String ETERNAL_CACHE = "eternal_cache";
    private final static String SYS_DICT = "sys_dict";
    private final static String SYS_CONFIG = "sys_config";
    private final static String REPEAT_SUBMIT = "repeat_submit";
    private final static String CAPTCHA_CODES = "captcha_codes";
    private final static String LOGIN_TOKENS = "login_tokens";
    private final static String RATE_LIMIT = "rate_limit";
    private final static String PWD_ERR_CNT = "pwd_err_cnt";
    @Bean
    public CacheManager ehcacheManager() {
        //配置占用资源
        //heap 设置占用虚拟机内存大小
        //offheap 设置占用虚拟机外内存大小
        //disk 设置占用磁盘空间大小，需结合下方ehcacheManager设置存储位置，否则会报错
        ResourcePoolsBuilder resourcePoolsBuilder =ResourcePoolsBuilder.newResourcePoolsBuilder().heap(20, MemoryUnit.MB).offheap(30, MemoryUnit.MB);
        //配置存储键值格式及过期策略
        //如:withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofHours(24)) 最后一次使用后计算，所存储的时间超过24小时
        //如：withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(24))) 从缓存开始计算，所存储的时间超过24小时
        //如：withExpiry(ExpiryPolicyBuilder.noExpiration()) 永不过期

        CacheConfiguration<String, Object> cacheConfiguration_temp_cache = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(1800)))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(1800)))
                .build();

        CacheConfiguration<String, Object> cacheConfiguration_eternal_cache = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.noExpiration())
                .build();

        CacheConfiguration<String, Object> cacheConfiguration_sys_dict = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.noExpiration())
                .build();

        CacheConfiguration<String, String> cacheConfiguration_sys_config = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.noExpiration())
                .build();

        CacheConfiguration<String, Object> cacheConfiguration_repeat_submit = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(5)))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(5)))
                .build();

        CacheConfiguration<String, String> cacheConfiguration_captcha_codes = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(180)))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(180)))
                .build();

        CacheConfiguration<String, Object> cacheConfiguration_rate_limit = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(180)))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(180)))
                .build();

        CacheConfiguration<String, LoginUser> cacheConfiguration_login_tokens = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, LoginUser.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(1800)))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(1800)))
                .build();

        CacheConfiguration<String, Object> cacheConfiguration_pwd_err_cnt = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder)
                .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))
                .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(1800)))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(1800)))
                .build();
        //获取最终打包jar所在位置
        String path = new ApplicationHome(getClass()).getSource().getParentFile().toString();
        System.out.println(path);
        //以下各行配置分别对应
        //配置硬盘缓存存储地址
        //最大对象默认大小
        //缓存记录最大条数
//        CacheManager ehcacheManager = CacheManagerBuilder.newCacheManagerBuilder()
//                .with(CacheManagerBuilder.persistence(new File(path, "ehcache")))
//                .withDefaultSizeOfMaxObjectSize(500, MemoryUnit.KB)
//                .withDefaultSizeOfMaxObjectGraph(2000)
//                .withCache(TEMP_CACHE , cacheConfiguration_temp_cache)
//                .withCache(ETERNAL_CACHE , cacheConfiguration_eternal_cache)
//                .withCache(SYS_DICT , cacheConfiguration_sys_dict)
//                .withCache(SYS_CONFIG , cacheConfiguration_sys_config)
//                .withCache(REPEAT_SUBMIT , cacheConfiguration_repeat_submit)
//                .withCache(CAPTCHA_CODES , cacheConfiguration_captcha_codes)
//                .withCache(LOGIN_TOKENS , cacheConfiguration_login_tokens)
//                .withCache(RATE_LIMIT , cacheConfiguration_rate_limit)
//                .withCache(PWD_ERR_CNT , cacheConfiguration_pwd_err_cnt)
//                .build(true);
        CachingProvider cachingProvider = Caching.getCachingProvider();
        CacheManager ehcacheManager = cachingProvider.getCacheManager();
        ehcacheManager.createCache(TEMP_CACHE, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_temp_cache));
        ehcacheManager.createCache(ETERNAL_CACHE, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_eternal_cache));
        ehcacheManager.createCache(SYS_DICT, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_sys_dict));
        ehcacheManager.createCache(SYS_CONFIG, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_sys_config));
        ehcacheManager.createCache(REPEAT_SUBMIT, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_repeat_submit));
        ehcacheManager.createCache(CAPTCHA_CODES, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_captcha_codes));
        ehcacheManager.createCache(LOGIN_TOKENS, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_login_tokens));
        ehcacheManager.createCache(RATE_LIMIT, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_rate_limit));
        ehcacheManager.createCache(PWD_ERR_CNT, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration_pwd_err_cnt));
        return ehcacheManager;

    }
}
